/*
 *  Cero Project - Copyright   2006 The Cero Developement Team 
 *  (Michael Laguerre, Camille Roux, Matthieu Segret, Mathieu Sivade) 
 * 
 *  This program is free software; you can redistribute it and/or modify it 
 *  under the terms of the GNU General Public License as published by the Free 
 *  Software Foundation; either version 2 of the License, or (at your option) 
 *  any later version.
 * 
 *  This program is distributed in the hope that it will be useful, but 
 *  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
 *  or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 
 *  for more details.
 */

package org.ceroproject.games.base;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.ceroproject.Sorter;
import org.ceroproject.games.Action;
import org.ceroproject.games.ActionListener;
import org.ceroproject.games.ActionRule;
import org.ceroproject.games.Game;
import org.ceroproject.games.InitializationException;
import org.ceroproject.games.Player;
import org.ceroproject.games.Rule;
import org.ceroproject.games.ValidationException;


/**
 * This rule will update the game's player list so that the first player of the
 * list is the "current" player in the sorted list. If you happen to use a
 * different "play" action than ActionPlayCards, then just override
 * listenedAction. If you want to listen to more than one Action type, you will
 * need to override onExecuted too.
 * 
 * @author Telem
 */
public class RulePlayInCircle implements Rule, ActionListener, Sorter<Player>, ActionRule {

	public String getRuleName() {
		return "Players play in round";
	}

	public String getRuleDescription() {
		return "Defines an order between the players and keeps it updated";
	}

	public String getRuleConstraints() {
		return null;
	}

	public void validateGame(Game game) throws ValidationException {
		if (game.getPlayers().size() < 1)
			throw new ValidationException(
					"You can't play a game with no player !");
		// I suppose there are no games we can't be used in, apart from stupid
		// cases like this one
	}

	public void onPlayerPlayed(Action action) {

	}

	public void onExecuted(Action action) {
		action.getEvent().getGame().getPlayers().sort(this);
	}

	public void onFailed(Action action) {

	}

	public Class listenedAction() {
		return ActionPlayYourCards.class;
	}

	/**
	 * Updates the player's list to have the first player become the last
	 * 
	 * @param players
	 *            the player list to update
	 */
	public List<Player> sort(Collection<Player> data) {
		List<Player> players = new ArrayList<Player>(data);
		Player tmp = players.get(0);
		players.remove(0);
		players.add(players.size(), tmp);
		return players;
	}

	public void initializeRule(Game game) throws InitializationException {
		game.addActionListener(this);
	}

	public boolean allowsAction(Action action) {
		return false;
	}

	public boolean forbidsAction(Action action) {
		return action.getPlayer() != action.getGame().getPlayers().getSortedList().get(0);
	}

	public Class ruledAction() {
		return ActionPlayYourCards.class;
	}

}
